package com.example.daxiguaforharmony.game.core;

import com.example.daxiguaforharmony.game.GameScene;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.utils.DimensFloat;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.multimodalinput.event.TouchEvent;

import java.util.Timer;

import java.util.TimerTask;

public class GameEventHander extends EventHandler implements Component.TouchEventListener {
    private DirectionalLayout _layout = null;
    private GameScene _scene = null;
    private GameRenderTask _renderTask = null;
    private Timer _initTimer = null;
    private Timer _updateTimer = null;
    private float _frameTime = 0;
    private boolean _inited = false;
    private boolean _stopUpdateTimerFlag = true;
    private GameEvent.GameCallback _gameCallback = null;

    public GameEventHander(EventRunner runner, DirectionalLayout layout, GameEvent.GameCallback gameCallback) {
        super(runner);
        this._layout = layout;
        this._frameTime = 1f / 60f;
        this._gameCallback = gameCallback;
        this._renderTask = new GameRenderTask();
        this._layout.addDrawTask(this._renderTask);
    }

    public void startup() {
        startInit();
    }

    public void stopTimer() {
        if (this._inited == true && this._updateTimer != null) {
            this._updateTimer.cancel();
            this._updateTimer = null;
            this._stopUpdateTimerFlag = true;
        }
    }

    public void startTimer() {
        if (this._inited == true && this._updateTimer == null && this._stopUpdateTimerFlag == true) {
            this._stopUpdateTimerFlag = false;
            final GameEventHander gameHandler = this;
            this._updateTimer = new Timer();
            this._updateTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    gameHandler.sendEvent(GameEvent.RENDER, 0);
                }
            }, 0, (long)(this._frameTime * 1000f));
        }
    }

    private void initGame() {
        if (this._scene != null) return;

        DimensFloat size = this._layout.getComponentSize();

        this._scene = new GameScene(size.getSizeX(), size.getSizeY());
        this._scene.setGameCallback((GameScene.GameSceneCallback)this._gameCallback);
        this._scene.setup();
        if (this._gameCallback != null) {
            this._gameCallback.onInitComplete(this._scene);
        }
        this._renderTask.initScene(this._scene);
        this._layout.setTouchEventListener(this);
        this._layout.addDrawTask(this._renderTask);
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        this._scene.onTouchEvent(touchEvent);
        return true;
    }

    @Override
    public void processEvent(InnerEvent event) {
        super.processEvent(event);
        if (event == null) return;
        int eventId = event.eventId;
        if (eventId == GameEvent.RENDER) {
            this._scene.step();
            this._scene.update(this._frameTime);
            this._layout.addDrawTask(this._renderTask);
        } else if (eventId == GameEvent.INIT) {
            DimensFloat size = this._layout.getComponentSize();
            if (size.getSizeX() > 0 && size.getSizeY() > 0) {
                if (this._initTimer != null) {
                    this._initTimer.cancel();
                    this._initTimer = null;
                    this._inited = true;
                    this.initGame();
                    this.startRender();
                }
            }
        }
    }

    private void startRender() {
        final GameEventHander gameHandler = this;
        this._updateTimer = new Timer();
        this._updateTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                gameHandler.sendEvent(GameEvent.RENDER, 0);
            }
        }, 0, (long)(this._frameTime * 1000f));
    }

    private void startInit() {
        final GameEventHander gameHandler = this;
        this._initTimer = new java.util.Timer();
        this._stopUpdateTimerFlag = false;
        this._initTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                gameHandler.sendEvent(GameEvent.INIT, 0);
            }
        }, 0, 5);
    }
}
